home *** CD-ROM | disk | FTP | other *** search
- -- __________ __________ __________ __________ ________
- -- / _______/ / ____ / / _______/ / _______/ / ____ \
- -- / / _____ / / / / / /______ / /______ / /___/ /
- -- / / /_ / / / / / / _______/ / _______/ / __ __/
- -- / /___/ / / /___/ / / / / /______ / / \ \
- -- /_________/ /_________/ /__/ /_________/ /__/ \__\
- --
- -- Functional programming environment, Version 2.28
- -- Copyright Mark P Jones 1991-1993.
- --
- -- Minimal Gofer prelude for experimentation with different approaches
- -- to standard operations.
- --
- -- Any Gofer prelude file should typically include at least the following
- -- definitions:
-
- infixr 5 :
- infixr 3 &&
- infixr 2 ||
-
- (&&), (||) :: Bool -> Bool -> Bool
- False && _ = False -- (&&) and (||) names predefined in Gofer
- True && x = x
- False || x = x
- True || _ = True
-
- flip :: (a -> b -> c) -> b -> a -> c
- flip f x y = f y x
-
- -- Primitives -----------------------------------------------------------
-
- primitive error "primError" :: String -> a
-
- -- End of minimal prelude ----------------------------------------------
-
- primitive strict "primStrict" :: (a -> b) -> a -> b
-
- -- Format primitives ----------------------------------------------------
-
- primitive primPrint "primPrint" :: Int -> a -> String -> String
- primitive primShowsInt "primShowsInt" :: Int -> Int -> String -> String
- primitive primShowsFloat "primShowsFloat" ::
- Int -> Float -> String -> String
-
- -- Character primitives -------------------------------------------------
-
- primitive primEqChar "primEqChar",
- primLeChar "primLeChar" :: Char -> Char -> Bool
- primitive ord "primCharToInt" :: Char -> Int
- primitive chr "primIntToChar" :: Int -> Char
-
- -- Integer primitives --------------------------------------------------
-
- primitive primEqInt "primEqInt",
- primLeInt "primLeInt" :: Int -> Int -> Bool
- primitive primPlusInt "primPlusInt",
- primMinusInt "primMinusInt",
- primDivInt "primDivInt",
- primMulInt "primMulInt" :: Int -> Int -> Int
- primitive primNegInt "primNegInt" :: Int -> Int
- primitive quot "primQuotInt",
- rem "primRemInt",
- mod "primModInt" :: Int -> Int -> Int
-
-
- -- Float primitives ---------------------------------------------------
-
- primitive primEqFloat "primEqFloat",
- primLeFloat "primLeFloat" :: Float -> Float -> Bool
- primitive primPlusFloat "primPlusFloat",
- primMinusFloat "primMinusFloat",
- primDivFloat "primDivFloat",
- primMulFloat "primMulFloat" :: Float -> Float -> Float
- primitive primNegFloat "primNegFloat" :: Float -> Float
- primitive primIntToFloat "primIntToFloat" :: Int -> Float
- primitive truncate "primFloatToInt" :: Float -> Int
-
- -- Trigonometric primitives ------------------------------------
-
- primitive sin "primSinFloat", asin "primAsinFloat",
- cos "primCosFloat", acos "primAcosFloat",
- tan "primTanFloat", atan "primAtanFloat",
- primLogFloat "primLogFloat", log10 "primLog10Float",
- primExpFloat "primExpFloat", sqrt "primSqrtFloat"
- :: Float -> Float
- primitive atan2 "primAtan2Float" :: Float -> Float -> Float
-
- -- IO ------------------------------------------------------------
-
- stdin = "stdin"
- stdout = "stdout"
- stderr = "stderr"
- stdecho = "stdecho"
-
- {- The Dialogue, Request, Response and IOError datatypes are now built-in:
- data Request = -- file system requests:
- ReadFile String
- | WriteFile String String
- | AppendFile String String
- -- channel system requests:
- | ReadChan String
- | AppendChan String String
- -- environment requests:
- | Echo Bool
- | GetArgs
- | GetProgName
- | GetEnv String
-
- data Response = Success
- | Str String
- | Failure IOError
- | StrList [String]
-
- data IOError = WriteError String
- | ReadError String
- | SearchError String
- | FormatError String
- | OtherError String
-
- type Dialogue = [Response] -> [Request]
- -}
-
- run :: (String -> String) -> Dialogue
- run f ~(Success : ~(Str kbd : _))
- = [Echo False, ReadChan "stdin", AppendChan "stdout" (f kbd)]
-
- primitive primFopen "primFopen" :: String -> a -> (String -> a) -> a
-
- openfile :: String -> String
- openfile f = primFopen f (error ("can't open file "++f)) id
-
- --- Fixities ------------------------------------------------------------
-
- infixl 9 !!
- infixr 9 .
- infixr 8 ^
- infixl 7 *, :/, /
- infix 7 `quot`, `rem`, `mod`
- infixl 6 +, -, :+!
- infixr 5 ++
- infix 4 ==, /=, <, <=, >=, >
- infixl 2 `bind`, `hcf`
-
- -- Standard synonyms --------------------
-
- type Rel a = a -> a -> Bool
- type BinOp a = a -> a -> a
-
- -- Standard type classes: -----------------------------------------------
-
- class Eq a where
- (==), (/=) :: Rel a
- x /= y = not (x == y)
- -- (x == x) === True
- -- (x == y) === (y == x)
- -- (x == y) && (y == z) ==> (x == z)
-
- class Eq a => Ord a where
- (<), (<=), (>), (>=) :: Rel a
- max, min :: BinOp a
-
- x < y = x <= y && x /= y
- x >= y = y <= x
- x > y = y < x
-
- max x y | x >= y = x
- | y >= x = y
- min x y | x <= y = x
- | y <= x = y
-
- -- x <= x === True
- -- (x <= y) && (y <= z) ==> (x <= z)
-
- class Ord a => Ix a where
- range :: (a,a) -> [a]
- index :: (a,a) -> a -> Int
- inRange :: (a,a) -> a -> Bool
-
- class Ord a => Enum a where
- enumFrom :: a -> [a] -- [n..]
- enumFromThen :: a -> a -> [a] -- [n,m..]
- enumFromTo :: a -> a -> [a] -- [n..m]
- enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m]
-
- enumFromTo n m = takeWhile (m>=) (enumFrom n)
- enumFromThenTo n n' m = takeWhile ((if n'>=n then (>=) else (<=)) m)
- (enumFromThen n n')
-
- class LeftMul a b where
- (*) :: a -> b -> b
-
- class Add a where
- (+),(-) :: BinOp a
- negate :: a -> a
- zero :: a
- negate x = zero - x
- -- x + (y + z) === (x + y) + z
- -- x + y === y + x
- -- zero + x === x
- -- x + zero === x
- -- x - x === zero
-
- class LeftMul a a => Mult a where
- unit :: a
- (^) :: a -> Int -> a
- x ^ 0 = unit
- x ^ 1 = x
- x ^ (2*n) = (x*x)^n
- x ^ (2*n+1) = x*(x*x)^n
- -- x*(y*z) === (x*y)*z
- -- unit*x === x
-
- class Div a b where
- (/) :: a -> b -> a
-
- class (Div a a, Add a, Mult a, Div a Int, LeftMul Int a) => Exp a where
- exp, log, cosh, sinh, tanh :: a -> a
- cosh x = (exp(x) + exp(-x))/2
- sinh x = (exp(x) - exp(-x))/2
- tanh x = (a-unit)/(a+unit) where a = exp(2*x)
-
- class Functor f where
- map :: (a -> b) -> (f a -> f b)
- -- map (u.v) === (map u).(map v)
- -- map id === id
-
- class Functor m => Monad m where
- result :: a -> m a
- join :: m (m a) -> m a
- bind :: m a -> (a -> m b) -> m b
- join x = bind x (\y->y)
- x `bind` f = join (map f x)
- -- (map u).result === result.(map u)
- -- (map u).join === join.(map (map u))
- -- join.(map result) === id
- -- join.result === id
- -- join.join === join.(map join)
-
- class Monad m => Monad0 m where
- nil :: m a
- -- map _ nil === nil
- -- join nil === nil
-
- class Monad0 c => MonadPlus c where
- (++) :: c a -> c a -> c a
- -- nil ++ x === x
- -- x ++ (y ++ z) === (x ++ y) ++ z
-
- -- A trimmed down version of the Haskell Text class: ---------------------
-
- type ShowS = String -> String
-
- class Text a where
- showsPrec :: Int -> a -> ShowS
- showList :: [a] -> ShowS
- showsPrec = primPrint
- showList [] = showString "[]"
- showList (x:xs) = showChar '[' . shows x . showl xs
- where showl [] = showChar ']'
- showl (x:xs) = showChar ',' . shows x . showl xs
-
- shows :: Text a => a -> ShowS
- shows = showsPrec 0
-
- show :: Text a => a -> String
- show x = shows x ""
-
- showChar :: Char -> ShowS
- showChar = (:)
-
- showString :: String -> ShowS
- showString = (++)
-
-
- -- Type class instances: -------------------------------------------
-
- instance Eq () where () == () = True
- instance Ord () where () <= () = True
-
- instance Eq Int where (==) = primEqInt
-
- instance Ord Int where (<=) = primLeInt
-
- instance Ix Int where
- range (m,n) = [m..n]
- index (m,n) i = primMinusInt i m
- inRange (m,n) i = m <= i && i <= n
-
- instance Enum Int where
- enumFrom n = iterate (primPlusInt 1) n
- enumFromThen n m = iterate (primPlusInt (primMinusInt m n)) n
-
- instance Eq Float where (==) = primEqFloat
-
- instance Ord Float where (<=) = primLeFloat
-
- instance Enum Float where
- enumFrom n = iterate (primPlusFloat 1.0) n
- enumFromThen n m = iterate (primPlusFloat (primMinusFloat m n)) n
-
- instance Eq Char where (==) = primEqChar -- c == d = ord c == ord d
-
- instance Ord Char where (<=) = primLeChar -- c <= d = ord c <= ord d
-
- instance Ix Char where
- range (c,c') = [c..c']
- index (c,c') ci = primMinusInt (ord ci) (ord c)
- inRange (c,c') ci = ord c <= i && i <= ord c' where i = ord ci
-
- instance Enum Char where
- enumFrom c = [chr n | n <- [ord c .. 255]]
- enumFromThen c c' = [chr n | n <- [ord c, ord c' .. ord lastChar]]
- where lastChar = if c' < c then (chr 0) else (chr 255)
-
- instance Eq a => Eq [a] where
- [] == [] = True
- [] == (y:ys) = False
- (x:xs) == [] = False
- (x:xs) == (y:ys) = x==y && xs==ys
-
- instance Ord a => Ord [a] where
- [] <= _ = True
- (_:_) <= [] = False
- (x:xs) <= (y:ys) = x<y || (x==y && xs<=ys)
-
- instance (Eq a, Eq b) => Eq (a,b) where
- (x,y) == (u,v) = x==u && y==v
-
- instance (Eq a, Eq b, Eq c) => Eq (a,b,c) where
- (x,y,z) == (u,v,w) = x == u && y == v && z == w
-
- instance (Ord a, Ord b) => Ord (a,b) where
- (x,y) <= (u,v) = x<u || (x==u && y<=v)
-
- instance (Ord a, Ord b, Ord c) => Ord (a,b,c) where
- (x,y,z) <= (u,v,w) = x<u || (x == u && ( y<v || (y==v && z<=w)))
-
- instance Eq Bool where
- True == True = True
- False == False = True
- _ == _ = False
-
- instance Ord Bool where
- False <= x = True
- True <= x = x
-
- instance LeftMul Int Int where
- (*) = primMulInt
-
- instance LeftMul Int Float where
- (*) n = primMulFloat(primIntToFloat n)
-
- instance LeftMul Float Float where
- (*) = primMulFloat
-
- instance (LeftMul a b, LeftMul a c) => LeftMul a (b,c)
- where a * (b,c) = (a*b, a*c)
-
- instance (LeftMul a b, LeftMul a c, LeftMul a d) => LeftMul a (b,c,d)
- where a * (b,c,d) = (a*b, a*c, a*d)
-
- instance LeftMul (a->a) (b->a)
- where (*) = (.)
-
- instance Add Int
- where (+) = primPlusInt
- (-) = primMinusInt
- negate = primNegInt
- zero = 0
-
- instance Add Float
- where (+) = primPlusFloat
- (-) = primMinusFloat
- negate = primNegFloat
- zero = 0.0
-
- instance (Add a, Add b) => Add (a,b)
- where (a,b) + (a',b') = (a+a',b+b')
- (a,b) - (a',b') = (a-a',b-b')
- negate (a,b) = (-a,-b)
- zero = (zero,zero)
-
- instance (Add a, Add b, Add c) => Add (a,b,c)
- where (a,b,c) + (a',b',c') = (a+a',b+b',c+c')
- (a,b,c) - (a',b',c') = (a-a',b-b',c-c')
- negate (a,b,c) = (-a,-b,-c)
- zero = (zero,zero,zero)
-
- instance Add a => Add (b->a)
- where f + f' = \b -> (f b)+(f' b)
- f - f' = \b -> (f b)-(f' b)
- - f = \b -> -(f b)
- zero = \b -> zero
-
- instance Mult Int
- where unit = 1
-
- instance Mult Float
- where unit = 1.0
-
- instance Mult (a->a)
- where unit = \x -> x
-
- instance Div Int Int
- where (/) = primDivInt
-
- instance Div Float Float
- where (/) = primDivFloat
-
- instance Div Float Int
- where x/n = x/(primIntToFloat n)
-
- instance Exp Float
- where exp = primExpFloat
- log = primLogFloat
-
- instance Functor [] where map f [] = []
- map f (x:xs) = f x : map f xs
-
- instance Monad [] where result x = [x]
- [] `bind` f = []
- (x:xs) `bind` f = f x ++ (xs `bind` f)
-
- instance Monad0 [] where nil = []
-
- instance MonadPlus [] where [] ++ ys = ys
- (x:xs) ++ ys = x : (xs ++ ys)
-
- instance Text () where
- showsPrec d () = showString "()"
-
- instance Text Bool where
- showsPrec d True = showString "True"
- showsPrec d False = showString "False"
-
- instance Text Int where showsPrec = primShowsInt
-
- instance Text Float where showsPrec = primShowsFloat
-
- instance Text Char where
- showsPrec p c = showString [q, c, q] where q = '\''
- showList cs = showChar '"' . showl cs
- where showl "" = showChar '"'
- showl ('"':cs) = showString "\\\"" . showl cs
- showl (c:cs) = showChar c . showl cs
-
- instance Text a => Text [a] where
- showsPrec p = showList
-
- instance (Text a, Text b) => Text (a,b) where
- showsPrec p (x,y) = showChar '(' . shows x . showChar ',' .
- shows y . showChar ')'
-
- ----- standard list functions used in prelude ----------------
-
- (!!) :: [a] -> Int -> a -- xs!!n selects the nth element of
- (x:_) !! 0 = x -- the list xs (first element xs!!0)
- (_:xs) !! (n+1) = xs !! n -- for any n < length xs.
-
- iterate :: (a -> a) -> a -> [a] -- generate the infinite list
- iterate f x = x : iterate f (f x) -- [x, f x, f (f x), ...
-
- take :: Int -> [a] -> [a]
- take 0 _ = []
- take _ [] = []
- take (n+1) (x:xs) = x : take n xs
-
- takeWhile :: (a -> Bool) -> [a] -> [a]
- takeWhile p [] = []
- takeWhile p (x:xs)
- | p x = x : takeWhile p xs
- | otherwise = []
-
- ----- standard Boolean values used in prelude -------------------
-
- otherwise :: Bool
- otherwise = True
-
- not :: Bool -> Bool
- not True = False
- not False = True
-
- ------- standard arithmetic functions ------------------
-
- abs :: (Add a, Ord a) => a -> a
- abs x | x < zero = -x
- | otherwise = x
-
- signum :: (Add a, Ord a) => a -> Int
- signum x | x > zero = 1
- | x < zero = -1
- | x == zero = 0
-
- hcf :: BinOp Int
- hcf x 0 = x
- hcf x y = hcf y (x `mod` y)
-
- sum :: Add a => [a] -> a
- sum [] = zero
- sum (x:xs) = x + sum xs
-
- product :: Mult a => [a] -> a
- product [] = unit
- product (x:xs) = x*product xs
-
- pi :: Float
- pi = 3.1415926535
-
- ------- standard combinators ----------------------
-
- (.) :: (b -> c) -> (a -> b) -> (a -> c)
- (f . g) x = f (g x)
-
- id :: a -> a
- id x = x
-
- undefined :: a
- undefined | False = undefined
-
- ---- Rationals -------------------------------------
-
- data Rational = Int :/ Int
-
- instance Eq Rational where
- (n :/ d) == (n' :/ d') = n*d' == n'*d
-
- instance LeftMul Rational Rational where
- (n :/ d) * (n' :/ d') = lowest ((n*n') :/ (d*d'))
-
- instance LeftMul Int Rational where
- m * (n :/ d) = lowest ((m*n) :/ d)
-
- instance LeftMul Rational Float where
- (n :/ d) * x = n*(x/(primIntToFloat d))
-
- instance Add Rational where
- (n :/ d) + (n' :/ d') = lowest ((n*d'+n'*d) :/ (d*d'))
- (n :/ d) - (n' :/ d') = lowest ((n*d'-n'*d) :/ (d*d'))
- negate (n :/ d) = ((-n) :/ d)
- zero = 0 :/ 1
-
- instance Mult Rational where
- unit = 1 :/ 1
-
- instance Div Rational Int where
- (n :/ d) / m = lowest (n :/ (d*m))
-
- instance Div Rational Rational where
- (n :/ d) / (n' :/ d') = lowest ((n*d') :/ (n'*d))
-
- instance Div Float Rational where
- x / (n :/ d) = (d*x)/n
-
- instance Ord Rational where
- (n :/ d) <= (n' :/ d') | d*d' > 0 = n*d' <= n'*d
- | otherwise = n*d' >= n'*d
-
- instance Enum Rational where
- enumFrom q = iterate (\(n:/d)->(n+d):/d) q
- enumFromThen q r = iterate (+ (r-q)) q
-
- instance Text Rational where
- showsPrec p (n :/ d) | d' == 1 = shows n'
- | otherwise = shows n'.showChar '/'.shows d'
- where (n' :/ d') = lowest (n :/ d)
-
- lowest (n :/ d) = (n/q) :/ (d/q) where q = (hcf n d)*(signum d)
-
- ------ Complexes -----------------------------------------------
-
- data Gauss a = a :+! a
-
- type Complex = Gauss Float
-
- instance (Eq a) => Eq (Gauss a) where
- (x :+! y) == (x' :+! y') = (x==x') && (y==y')
-
- instance (Mult a, Add a) => Mult (Gauss a) where
- unit = unit :+! zero
-
- instance (Add a) => Add (Gauss a) where
- (x :+! y) + (x' :+! y') = (x+x') :+! (y+y')
- (x :+! y) - (x' :+! y') = (x-x') :+! (y-y')
- negate (x :+! y) = (-x) :+! (-y)
- zero = zero :+! zero
-
- instance (LeftMul a b) => LeftMul a (Gauss b) where
- x * (y :+! z) = (x*y) :+! (x*z)
-
- instance (LeftMul a b, Add b) => LeftMul (Gauss a) (Gauss b) where
- (x :+! y) * (x' :+! y') = (x*x' - y*y') :+! (x*y' + y*x')
-
- instance Div a b => Div (Gauss a) b where
- (x :+! y)/d = (x/d) :+! (y/d)
-
- instance (Div a b, Add a, Add b, LeftMul b a, LeftMul b b, LeftMul a a)
- => Div (Gauss a) (Gauss b)
- where z / z' = (x/d) :+! (y/d)
- where x = u'*u+v'*v
- y = u'*v-v'*u
- d = u'*u'+v'*v'
- u:+!v = z
- u':+!v' = z'
-
- instance Exp Complex where
- exp (x :+! y) = let r = exp(x) in (r*cos(y)) :+! (r*(sin(y)))
- log (x :+! y) = let r=sqrt(x*x+y*y) in (log(r)) :+! (atan2 y x)
-
- instance (Text a, Add a, Mult a, Ord a) => Text (Gauss a)
- where
- showsPrec n (x :+! y) | y == zero = shows x
- | x == zero = showIm y
- | y > zero = shows x. showChar '+'. showIm y
- | y < zero = shows x. showChar '-'. showIm (-y)
- where showIm y | y == unit = showChar 'i'
- | y == (-unit) = showString "-i"
- | otherwise = shows y.showChar 'i'
-
- norm :: (Add a, LeftMul a a) => (Gauss a) -> a
- norm (x :+! y) = x*x + y*y
-
- conjugate :: Add a => (Gauss a) -> (Gauss a)
- conjugate (x :+! y) = x :+! (-y)
-
- i :: (Add a, Mult a) => (Gauss a)
- i = zero :+! unit
-
- -- end of gcwmin ------------------------------------------------